package cn.jimmie.lib.qlog.interceptor;

import android.Manifest;
import android.content.Context;
import android.os.Build;
import android.util.Pair;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import cn.jimmie.lib.qlog.Options;
import cn.jimmie.lib.qlog.support.AlApp;
import cn.jimmie.lib.qlog.support.AlChecker;
import cn.jimmie.lib.qlog.support.AlDevice;
import cn.jimmie.lib.qlog.support.AlNetWork;
import cn.jimmie.lib.qlog.support.AlProcess;
import cn.jimmie.lib.qlog.support.AlString;

/**
 * Func : 默认的固定信息拦截器
 *
 * <p> Create Time:  2019-12-18 14:47 </p>
 * <p> @author Jimmie.Qian  </p>
 */
public class CommonHeaderInterceptor implements HeaderInterceptor {
    // AppInfo
    private String appVersionName;
    private String appVersionCode;
    private String packageName;
    private String processName;
    private int processId;

    // deviceInfo
    private String networkType;
    private String model;
    private String brand;
    private String system;
    private String sdk;
    private int screenWidth;
    private int screenHeight;
    private String imei;
    private String imsi;
    private String androidId;

    private Options options;
    private boolean needCheckPhoneState = true;

    @Override
    public void init(Options options) {
        this.options = options;
        Context ctx = options.context();
        brand = Build.BRAND;
        model = Build.MODEL;
        imei = AlDevice.getImei(ctx);
        imsi = AlDevice.getImsi(ctx);
        androidId = AlDevice.getAndroidId(ctx);
        networkType = AlNetWork.getNetworkType(ctx);
        Pair<Integer, Integer> resolution = AlDevice.getResolution(ctx);
        screenWidth = resolution.first;
        screenHeight = resolution.second;
        packageName = ctx.getPackageName();
        appVersionName = AlApp.getVersion(ctx);
        appVersionCode = String.valueOf(AlApp.getVersionCode(ctx));
        system = Build.VERSION.RELEASE;
        sdk = "1.0.0" + "_" + 1;
        processId = AlProcess.myPid();
        processName = AlProcess.getProcessName(ctx);
    }

    @Override
    public String fixedInfo() {
        Context appCtx = options.context();
        if (needCheckPhoneState && AlChecker.isPermissionGranted(appCtx, Manifest.permission.READ_PHONE_STATE)) {
            imei = AlDevice.getImei(appCtx);
            imsi = AlDevice.getImsi(appCtx);
            androidId = AlDevice.getAndroidId(appCtx);
            needCheckPhoneState = false;
        }

        return "--- --- --- --- ---\n" +
                "appVersionName=" + appVersionName + "\t" +
                "appVersionCode=" + appVersionCode + "\t" +
                "processName=" + processName + "\n" +
                "processId=" + processId + "\n" +
                "packageName=" + packageName + "\n" +
                "brand=" + brand + "\t" +
                "model=" + model + "\t" +
                "system=" + system + "\t" +
                "sdk=" + sdk + "\t" +
                "screenWidth=" + screenWidth + "\t" +
                "screenHeight=" + screenHeight + "\n" +
                "imei=" + imei + "\t" +
                "imsi=" + imsi + "\t" +
                "androidId=" + androidId + "\n" +
                "--- --- --- --- ---\n";
    }

    private long checkNetworkTime;

    @Override
    public String prefixInfo() {
        // 网络监察 5秒 检查一次就够了
        long lastTime = System.currentTimeMillis();
        if (lastTime - checkNetworkTime > 5_000) {
            networkType = AlNetWork.getNetworkType(options.context());
            checkNetworkTime = lastTime;
        }

        return AlString.format("%s [%s] %s %s : ",
                timeFormat(), getCaller(), Thread.currentThread().getName(), networkType);
    }

    @Override
    public Options options() {
        return options;
    }

    private String getCaller() {
        StackTraceElement[] trace = new Throwable().fillInStackTrace().getStackTrace();

        String caller = "<unknown>";
        // Walk up the stack looking for the first caller outside of VolleyLog.
        // It will be at least two frames up, so update there.
        if (trace.length >= 6) {
            String callingClass = trace[5].getClassName();
            if (!AlString.empty(packageName))
                callingClass = callingClass.replace(packageName + ".", "");
            caller = callingClass + "." + trace[5].getMethodName();
        }
        return caller;
    }

    private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);

    private String timeFormat() {
        return dateFormat.format(new Date());
    }
}
// 2019-12-19 22:11:07.630 [MainActivity$1.onClick] main 4G : 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960